package com.atguigu.gmall.oms.listener;

import com.atguigu.gmall.oms.entity.OrderEntity;
import com.atguigu.gmall.oms.service.OrderService;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.rabbitmq.client.Channel;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Map;

@Configuration
public class OmsMqListener {
    @Autowired
    RabbitTemplate rabbitTemplate;
    @Autowired
    RedissonClient redissonClient;
    @Autowired
    StringRedisTemplate redisTemplate;
    @Autowired
    OrderService orderService;
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(name="sec.order.queue"),
                    exchange = @Exchange(name = "sec.exchange" ,type = ExchangeTypes.TOPIC
                            ,ignoreDeclarationExceptions = "true"),
                    key = "sec.kill.success"
            )
    })
    public void secOrderListener(Map<String ,Object> map , Message message,
                                          Channel channel) throws IOException {//skuId:xx 、price:xxx

        try {
            System.out.println("秒杀成功，创建订单："+map);
            //减库存
            redisTemplate.opsForValue().decrement("sec:kill:"+map.get("skuId"));
            //关闭闭锁
            redissonClient.getCountDownLatch("sec:cdl:"+map.get("orderToken"))
                .countDown();//闭锁值-1
            channel.basicAck(message.getMessageProperties().getDeliveryTag() , false);
        } catch (Exception e) {
            e.printStackTrace();
            if(message.getMessageProperties().isRedelivered()){
                //丢弃消息
                channel.basicReject(message.getMessageProperties().getDeliveryTag() , false);
            }else{
                channel.basicNack(message.getMessageProperties().getDeliveryTag() ,
                        false,true);
            }
        }
    }

    //orderToken：修改订单的状态为已支付状态
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(name="pay.order.queue"),
                    exchange = @Exchange(name = "pay.exchange" ,type = ExchangeTypes.TOPIC
                            ,ignoreDeclarationExceptions = "true"),
                    key = "pay.success"
            )
    })
    public void updateOrderStatusListener(String orderToken , Message message,
                                         Channel channel) throws IOException {//skuId:xx 、price:xxx

        try {
            orderService.update(new LambdaUpdateWrapper<OrderEntity>()
                .eq(OrderEntity::getOrderSn , orderToken)
                .eq(OrderEntity::getStatus,0)
                .set(OrderEntity::getStatus , 1));
            channel.basicAck(message.getMessageProperties().getDeliveryTag() , false);
        } catch (Exception e) {
            e.printStackTrace();
            if(message.getMessageProperties().isRedelivered()){
                //丢弃消息
                channel.basicReject(message.getMessageProperties().getDeliveryTag() , false);
            }else{
                channel.basicNack(message.getMessageProperties().getDeliveryTag() ,
                        false,true);
            }
        }
    }
    //order.dead.close.queue
    @RabbitListener(queues = "order.dead.close.queue")
    public void cartCurrentPriceListener(String orderToken , Message message,
                                         Channel channel) throws IOException {//skuId:xx 、price:xxx

        try {
            /*
                关单业务：
                    关单：修改订单状态为4即可
                    订单关闭还需要释放库存
             */
            //修改订单状态为4
            boolean update = orderService.update(new LambdaUpdateWrapper<OrderEntity>()
                    .eq(OrderEntity::getOrderSn, orderToken)
                    .eq(OrderEntity::getStatus, 0) //只有状态为0时才关闭订单
                    .set(OrderEntity::getStatus, 4));
            //只有订单超时未支付时才释放库存
            if(update){
                rabbitTemplate.convertAndSend("order.exchange",
                        "stock.unlock" , orderToken);
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag() , false);
        } catch (Exception e) {
            e.printStackTrace();
            if(message.getMessageProperties().isRedelivered()){
                //丢弃消息
                channel.basicReject(message.getMessageProperties().getDeliveryTag() , false);
            }else{
                channel.basicNack(message.getMessageProperties().getDeliveryTag() ,
                        false,true);
            }
        }
    }


}
